using System;
using System.Linq;
using System.Linq.Expressions;
using Budget.Core.Extensions;

namespace Budget.Core.Specifications.Base
{
    internal class QuerySpecification<T> : Specification<T>
    {
        private readonly Expression<Func<T, bool>> expression;

        protected override Expression<Func<T, bool>> Predicate
        {
            get
            {
                return this.expression;
            }
        }

        public QuerySpecification(Expression<Func<T, bool>> expression)
        {
            this.expression = expression;
        }

        public static Specification<T> operator !(QuerySpecification<T> specification)
        {
            return new QuerySpecification<T>(specification.Predicate.Not());
        }

        public static Specification<T> operator |(QuerySpecification<T> left, QuerySpecification<T> right)
        {
            return new QuerySpecification<T>(left.Predicate.Or(right.Predicate));
        }

        public static QuerySpecification<T> operator &(QuerySpecification<T> left, QuerySpecification<T> right)
        {
            return new QuerySpecification<T>(left.Predicate.And(right.Predicate));
        }


        public static implicit operator Expression<Func<T, bool>>(QuerySpecification<T> specification)
        {
            return specification.Predicate;
        }
    }
}